#include "niveau.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>


        /*  CONSTANTES */

const int DIMY = 0;
const int DIMX = 0;
const int DIMENSION_CASE = 20;


        /*  DECLARATIONS FONCTIONS INTERNES AU MODULE */

void I_AfficherNiveau(NIVEAU* terrain);
void I_TestGet(NIVEAU *terrain);
void I_ProgrammeTest();


        /*  ACCESSEURS */

int GetDimXNiveau(const NIVEAU *terrain)
{
    assert(terrain);
    return terrain->dimX;
}

int GetDimYNiveau(const NIVEAU *terrain)
{
    assert(terrain);
    return terrain->dimY;
}

char GetCaseNiveau(const NIVEAU *terrain, const int x, const int y)
{
    assert(x>=0 && x<terrain->dimX && y>=0 && y<terrain->dimY && terrain);
    return terrain->cases[y*terrain->dimX+x];
}

char GetCaseNiveauPixel(const NIVEAU *terrain, const int x, const int y)
{
    assert(terrain);
    return GetCaseNiveau(terrain, x/terrain->dimensionCase, y/terrain->dimensionCase);
}

int GetDimensionCaseNiveau(const NIVEAU *terrain)
{
    assert(terrain);
    return terrain->dimensionCase;
}


        /*  MUTATEURS */

void SetCaseNiveau(NIVEAU *niveau, const int x, const int y, const char caractere)
{
    assert(x>=0 && x<niveau->dimX && y>=0 && y<niveau->dimY && niveau);
    niveau->cases[y*niveau->dimX+x] = caractere;
}

void SetDimXNiveau(NIVEAU *niveau, const int x)
{
    niveau->dimX = x;
}

void SetDimYNiveau(NIVEAU *niveau, const int x)
{
    niveau->dimY = x;
}


        /*  AUTRES FONCTIONS */

NIVEAU* CreerNiveau()
{
    NIVEAU* terrain = (NIVEAU*) malloc(sizeof(NIVEAU));
    assert(terrain);
    InitialiserNiveau(terrain);
    return terrain;
}

void InitialiserNiveau(NIVEAU *terrain)
{
    terrain->dimX = 0;
    terrain->dimY = 0;
    terrain->cases = NULL;
    terrain->dimensionCase = DIMENSION_CASE;
}

void TestamentNiveau(NIVEAU **terrain)
{
	assert(*terrain);
	free((*terrain)->cases);
	(*terrain)->cases=NULL;
	free(*terrain);
}

void ChargerNiveau(NIVEAU *terrain, FILE * f)
{
	int testlecture;
    char tmp;       /*  tampon pour gérer le \n dans le fichier à la fin de chaque ligne */
    int i,j;

	printf("\tChargement du terrain");
	testlecture=fscanf( f,"%d\n%d\n",&(terrain->dimX) ,&(terrain->dimY));      /*  lecture des dimensions du tableau */
    if (testlecture != 2)
    {
		fprintf(stderr,"Mauvais format de niveau\n");
		exit(EXIT_SUCCESS);
	}
	terrain->cases = (char*) malloc(terrain->dimX*terrain->dimY*sizeof(char));
    assert(terrain->cases);

    for(i=0 ; i<terrain->dimY ; i++)        /*  lecture des caractères du tableau */
    {
        for(j=0 ; j<terrain->dimX ; j++)
        {
            assert( fscanf( f,"%c", &tmp ) == 1 );      /* utilisation du tampon pour savoir si le caractère lu est \n */
            if(tmp != '\n')
            {
                terrain->cases[i*terrain->dimX+j] = tmp;        /*  si c'est pas \n c'est ok! */
            }
            else
            {
                assert( fscanf( f,"%c", &(terrain->cases[i*terrain->dimX+j]) ) == 1 );      /*  sinon on en relit un autre */
            }
        }
	printf(".");
    }
    printf("OK\n");
}

void FinNiveau(NIVEAU *terrain)
{
    assert(terrain);
    free(terrain->cases);
    terrain->cases = NULL;
    terrain->dimX = terrain->dimY = 0;
}

int ConversionPixelCase(const int nombre, const NIVEAU *niveau)
{
	return nombre/niveau->dimensionCase;
}

int ConversionCasePixel(const int nombre, const NIVEAU *niveau)
{
	return nombre*niveau->dimensionCase;
}

int EstUnMur(const NIVEAU *niveau, const int x, const int y)
{
	char Case;
	Case = GetCaseNiveauPixel(niveau,x,y);
	if (Case == '#')
	{
		return 1;
	}
	return 0;
}

int EstUnPic(const NIVEAU *niveau, const int x, const int y)
{
    char Case;
	Case = GetCaseNiveauPixel(niveau,x,y);
	if (Case == '^' || Case == 'v' || Case == '>' || Case == '<')
	{
		return 1;
	}
	return 0;
}

int EstEau(const NIVEAU *niveau, const int x, const int y)
{
	char Case;
	Case = GetCaseNiveauPixel(niveau,x,y);
	if (Case == '~')
	{
		return 1;
	}
	return 0;
}

int EstUnPicOuUnMur(const NIVEAU *niveau, const int x, const int y)
{
    if (EstUnPic(niveau, x, y) || EstUnMur(niveau, x, y))
    {
        return 1;
    }
    return 0;
}


        /* DEFINITIONS FONCTIONS INTERNES AU MODULE */

void I_AfficherNiveau(NIVEAU* terrain)
{


    int i,j;
    printf("\n --> entree dans I_AfficherNiveau \n\n");
    printf("x = %d et y = %d\n\n", terrain->dimX,terrain->dimY);
    for(i=0 ; i<terrain->dimY ; i++)
    {
        for(j=0 ; j<terrain->dimX ; j++)
        {
                  printf("%c", terrain->cases[i*terrain->dimX+j]);
        }
        printf("\n");
    }

    printf("\n <-- sortie de I_AfficherNiveau \n\n");
}

void I_TestGet(NIVEAU *terrain)
{
    int x,y;
    char uneCase;

    printf("\n --> entree dans I_TestGet \n\n");
    x = GetDimXNiveau(terrain);
    y = GetDimYNiveau(terrain);
    printf(" dimX = %d et dimY = %d\n", x,y);
    if(x!=0 && y!=0)
    {
        uneCase = GetCaseNiveau(terrain,0,0);
        printf(" La case 0 à la valeur %c\n", uneCase);
        uneCase = GetCaseNiveau(terrain,x-1,y-1);
        printf(" La derniere case à la valeur %c\n", uneCase);
    }

    /*uneCase = GetCaseNiveau(terrain,terrain->dimX,terrain->dimY);
    uneCase = GetCaseNiveau(terrain,0,-1);*/                        /*  test des asserts : valeurs éronées */

    printf("\n <-- sortie de I_TestGet \n\n");
}

/*
void I_ProgrammeTest()
{
    NIVEAU *niveau;

    printf("\n --> entree dans I_ProgrammeTest \n\n");

    niveau = NULL;
    niveau = CreerNiveau();
    ChargerNiveau(niveau,niveau1);
    I_AfficherNiveau(niveau);
    I_TestGet(niveau);
    FinNiveau(niveau);
    I_TestGet(niveau);
    ChargerNiveau(niveau,3);
    I_AfficherNiveau(niveau);
    I_TestGet(niveau);
    TestamentNiveau(&niveau);

    printf("\n <-- sortie de I_ProgrammeTest \n\n");
}
*/
